package com.rescueworkers;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.json.JSONObject;

import android.util.Log;

import com.fg114.main.service.dto.JsonPack;
import com.fg114.main.util.ActivityUtil;
import com.fg114.main.util.ContextUtil;
import com.fg114.main.util.DateUtils;
import com.fg114.main.util.SessionManager;

public class UploadFileUtils {

	private static String end = "\r\n";
	private static String twoHyphens = "--";
	private static String boundary = "---WebKitFormBoundaryr6SvZn0DT1sA5Rtq";
	// private static String boundary =
	// "---------------------------7de3a916a0ab0";
	private static String r_command = null;
	private static String taskId, latitudes, longitudes, acquisition_ats;

	public static JsonPack uploadFile(String uploadUrl, String filePath,
			String id, String latitude, String longitude,
			String acquisition_at, int type ) {
		JsonPack jsonPack = new JsonPack();
		taskId = id;
		latitudes = latitude;
		longitudes = longitude;
		acquisition_ats = acquisition_at;
		try {
			URL url = new URL(uploadUrl);
			HttpURLConnection httpURLConnection = (HttpURLConnection)  url
					.openConnection();
			// 设置每次传输的流大小，可以有效防止手机因为内存不足崩?
			// 此方法用于在预先不知道内容长度时启用没有进行内部缓冲?HTTP 请求正文的流?
			httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
			// 允许输入输出?
			httpURLConnection.setDoInput(true);
			httpURLConnection.setDoOutput(true);
			httpURLConnection.setUseCaches(false);
			// 使用POST方法
			httpURLConnection.setRequestMethod("POST");
			httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
			httpURLConnection.setRequestProperty("Charset", "UTF-8");
			httpURLConnection.setRequestProperty("Accept", "*/*");// 此处很重要
			httpURLConnection.setRequestProperty("Content-Type",
					"multipart/form-data;boundary=" + boundary);
			httpURLConnection.setRequestProperty(
					"Authorization",
					SessionManager.getInstance().getUserInfo(
							ContextUtil.getContext()).token);
			httpURLConnection.connect();
			DataOutputStream dos = new DataOutputStream(
					httpURLConnection.getOutputStream());
			try {
				StringBuffer sb = new StringBuffer();
				long currentTime = System.currentTimeMillis();
				sb.append("\n"+"request : url ----- time "+DateUtils.toDateString(currentTime, "yyyyMMdd")+"\n");
				sb.append("url-----"+uploadUrl+" \n");
				sb.append("request -----"+ "{filePath "+ filePath
						+ "}{id" + id + "}{latitude " + latitude + "}{longitude " +longitude
						+ "}{acquisition_at " + acquisition_at + "}{type " + type+"}");
//				FileUtils.WriteTxtFileNoDelete(sb.toString(), Settings.sdCardPath+Settings.APP_PATH+Settings.Log_path,
//						DateUtils.toDateString(currentTime, "yyyyMMdd")+".txt");
			} catch (Exception e) {
				e.printStackTrace();
			}
			writeParams(dos);
			writeImg(dos, filePath, type);

			dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
			dos.flush();
			Log.i("test", httpURLConnection.getResponseCode()+" response code");
			InputStream is = httpURLConnection.getInputStream();
			InputStreamReader isr = new InputStreamReader(is, "UTF-8");
			BufferedReader br = new BufferedReader(isr);
			String _str = "";
			r_command = "";
			while ((_str = br.readLine()) != null) {
				r_command = r_command + _str;
			}

			dos.close();
			is.close();
			Log.v("test", "upload success:" + r_command);

		} catch (Exception e) {
			e.printStackTrace();
			try {
				// service.SaveToSD("reply.txt", "#" + e.getMessage());
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			Log.v("test", "error:-------" + e.getMessage());
		}
		jsonPack = dealResponse(r_command, uploadUrl);
		return jsonPack;
	}
	
	final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {

		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	};
	
	
	private static void trustAllHosts() {
		final String TAG = "trustAllHosts";
		// Create a trust manager that does not validate certificate chains
		TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
	 
			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return new java.security.cert.X509Certificate[] {};
			}
	 
			public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				Log.i(TAG, "checkClientTrusted");
			}
	 
			public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				Log.i(TAG, "checkServerTrusted");
			}
		} };
	 
		// Install the all-trusting trust manager
		try {
			SSLContext sc = SSLContext.getInstance("TLS");
			sc.init(null, trustAllCerts, new java.security.SecureRandom());
			HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 写入参数
	 * 
	 * @param dos
	 */
	private static void writeParams(DataOutputStream dos) {
		writeSingleParam(dos, "worker_job_id", taskId);// "kitty|9C465BBCCC016EF5A59F6B32FA6AA069");//
		writeSingleParam(dos, "acquisition_at", acquisition_ats);
		writeSingleParam(dos, "latitude", latitudes);
		writeSingleParam(dos, "longitude", longitudes);
	}

	/**
	 * 写入单个参数
	 * 
	 * @param key
	 * @param value
	 */
	private static void writeSingleParam(DataOutputStream dos, String key,
			String value) {
		try {
			dos.writeBytes(twoHyphens + boundary + end);
			dos.writeBytes("Content-Disposition: form-data; name=\"" + key
					+ "\"" + end + end);
			dos.writeBytes(value + end);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 写入图片
	 * 
	 * @param dos
	 */
	private static void writeImg(DataOutputStream dos, String filePath, int type) {
		try {
			dos.writeBytes(twoHyphens + boundary + end);
			dos.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\""
					+ filePath.substring(filePath.lastIndexOf("/") + 1)
					+ "\""
					+ end);
			/*
			 * if(type == 0 ){ dos.writeBytes("Content-Type: image/jpeg" + end);
			 * }else{ dos.writeBytes("Content-Type: video/3gpp" + end); }
			 */
			dos.writeBytes(end);

			FileInputStream fis = new FileInputStream(filePath);
			byte[] buffer = new byte[8192]; // 8k
			int count = 0;
			// 读取文件
			while ((count = fis.read(buffer)) != -1) {
				dos.write(buffer, 0, count);
			}
			fis.close();
			dos.writeBytes(end);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static JsonPack dealResponse(String responseString, String url) {
		JsonPack jp = new JsonPack();
		try {
			// 设置返回值
			if (responseString != null && !"".equals(responseString)) {
				JSONObject jsonResponse = new JSONObject(responseString);

				jp.setRe(jsonResponse.getInt("code"));
				jp.setUrl(url);

				if (jp.getRe() == 500) {
					jp.setMsg("网络查询出现错误");
					Exception ex = new Exception("Exception 500 from server");
					String msg = "Exception 500 from server ";
					if (url != null) {
						msg += url;
					}
					ActivityUtil.saveException(ex, msg);
				} else {
					jp.setMsg(jsonResponse.getString("msg"));
				}

				if (jsonResponse.has("data")) {
					Object obj = jsonResponse.get("data");
					if (obj instanceof JSONObject) {
						JSONObject successResultObject = jsonResponse
								.getJSONObject("data");
						jp.setObj(successResultObject);
					}
				}
				
				try {
					StringBuffer sb = new StringBuffer();
					long currentTime = System.currentTimeMillis();
					sb.append("\n"+"result : url ----- time "+DateUtils.toDateString(currentTime, "yyyyMMdd")+"\n");
					sb.append("url-----"+url+" \n");
					sb.append("result -----" +responseString);
//					FileUtils.WriteTxtFileNoDelete(sb.toString(), Settings.sdCardPath+Settings.APP_PATH+Settings.Log_path,
//							DateUtils.toDateString(currentTime, "yyyyMMdd")+".txt");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		} catch (Exception e) {
			ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
			PrintWriter pw = new PrintWriter(bos, true);
			e.printStackTrace(pw);
			pw.flush();
		}

		return jp;
	}
}
